package server.version;

import server.RequestProcessor;
import server.loader.ServerLoader;
import server.loader.ServletLoader;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * Created by louisyuu on 2020/4/2 上午11:03
 * <p>
 * <p>
 * 为什么要Minicat4要自定义类加载器 并且没有严格遵循双亲委派机制
 * <p>
 * 在webapps下面也有demo.servlet.DemoServlet，如果严格按照双亲委派去加载Class那么会优先加载Classpath下面的DemoServlet
 * webapps的DemoServlet就不会被加载了，因为此时此刻在jvm内存中已经存在了demo.servlet.DemoServlet。
 * 这也是为什么tomcat要打破双亲委派机制的原因
 */
public class VersionFiveStarter implements VersionStater {


    @Override
    public void start() throws Exception {
        /**
         * 加载server start server容器
         */
        new ServerLoader().loadServer();


        ServletLoader servletLoader = new ServletLoader();

        /**
         * 加载minicat本身的Servlet
         */
        servletLoader.loadLocalServlet();

        /**
         * 加载webapps 使用双亲委派机制
         */
        servletLoader.loadWebAppServletsUseParentsDelegation();


        ServerSocket serverSocket = new ServerSocket(port);
        System.out.println("=====>>>Minicat start on port：" + port);

        int corePoolSize = 2;
        int maximumPoolSize = 4;
        long keepAliveTime = 20;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);

        //多线程改造（不使用线程池）
        while (true) {
            Socket socket = serverSocket.accept();
            RequestProcessor requestProcessor = new RequestProcessor(socket, ServletLoader.servletMap);
            executor.execute(requestProcessor);
        }
    }
}
